
#ifndef VehicleDetection_h
#define VehicleDetection_h

#pragma warning (disable:4251)

// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the DETECTORDLL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// DETECTORDLL_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#ifdef DETECTORDLL_EXPORTS
#define DETECTORDLL_API __declspec(dllexport)
#define EXPIMP_TEMPLATE
#else
#define DETECTORDLL_API __declspec(dllimport)
#define EXPIMP_TEMPLATE extern
#endif

#ifdef __cplusplus
extern "C" {
#endif

  //! @brief Pointer to hidden implementation of vehicle detector
  //!
  struct DETECTORDLL_API VehicleDetector;

  //! @brief Pointer to hidden implementation of vehicle detector
  //!
  struct DETECTORDLL_API VehicleHomography;

  //! @class VehicleDetectionConfiguration
  //!
  //! @brief A simple struct to save detection configurations
  //!
  struct DETECTORDLL_API VehicleDetectionConfiguration
  {

    //! @brief Type of detector configuration (Low, medium or high point on ROC Curve)
    //!
    int mconfigurationType;

    //! @brief If the frame being processed, is part of the some video sequence being processed
    //!
    bool mIsFrameContinuous;

    //! @brief switch paramter for search (False if the whole image is to be searched exhaustively,
    //! true if just a window inside the image is to be searched for vehicle detection)
    //!
    bool mWindowSearch;

    //! @brief the frame rate of the video
    //!
    double mFrameRate;

    //! @brief The camera angle
    //!
    double mAngle;

    //! @brief The cm. per pixel i.e. the resolution 
    //!
    double mCmPerPixel;

    //! @brief  left top x position of the window in the image
    //!
    double mWindowTopLeftX;

    //! @brief  left top y position of the window in the image
    //!
    double mWindowTopLeftY;

    //! @brief  width of the window
    //!
    double mWindowWidth;

    //! @brief  height of the window
    //!
    double mWindowHeight;

    //! @brief  height of the window
    //!
    VehicleHomography *mVehicleHomography;
  };

  //! @class VehicleHomography
  //!
  //! @brief a simple struct for frame to frame homography for the continuous frames
  //!
  struct DETECTORDLL_API VehicleHomography
  {
    //! @brief previous frame to which homograpgy matrix is mapped
    // (e.g. if mPreviousFrameIndex = 2 then current frame maps to
    // the (currentFrame -2).
    //!
    int mPreviousFrameIndex;

    //! @brief The Homography Matrix
    //!
    double mHomographyMatrix[3][3];
  };

  //! @class VehicleDetectionImage
  //!
  //! @brief A simple struct to represent image data
  //!
  //! The image is grayscale data
  //!
  struct DETECTORDLL_API VehicleDetectionImage
  {
    //! @brief Raw pointer to the image data
    //!
    unsigned char *mData;

    //! @brief The image width
    //!
    int mWidth;

    //! @brief The image height
    //!
    int mHeight;

    //! @brief The image stride (the number of bytes 
    //!        to get to the next image row)
    //!
    //!        pixelxy = mData[y * mStride + x];
    //!
    int mStride;

  };

  //! @class VehicleDetection
  //!
  //! @brief A ssimple struct to store single vehicle detection response
  //!
  struct DETECTORDLL_API VehicleDetection
  {
    //! @brief The center of the detection
    //!
    int mX;

    //! @brief The center of the detection
    //!
    int mY;

    //! @brief The width of the detection
    //!	
    int mWidth;           

    //! @brief The height of the detection
    //!
    int mHeight;

    //! @brief The identifier of the detection 
    //!
    //! If the detection is tracked between two frames, the
    //! id is used to associate detections. If not, a unique
    //! identifier should be used that does not repeat
    //!
    //! Identifiers should start at 0 and increment (always
    //! positive).
    //!
    int mIdentifier;

    //! @brief The confidence in the detection (0 is bad, 1 is good)
    //!
    float mConfidence;

    //! @brief The number of detection responses
    //!
    float mNumResponses;

    //! @brief whether the detection response is true or not
    //!
    int isValid;

  };

  //! @class VehicleDetectionResult
  //! 
  //! @brief A simple struct to store detection results
  //!
  struct DETECTORDLL_API VehicleDetectionResult;

  //! @brief Allocate a vehicle detection implementation
  //!
  //! @param[out] oVD		memory allocation to the pointer of hidden implementation
  //! @param[out] oVDC	memory allocation to detection configuration parameter
  //!
  //! @return Boolean indicating whether memory allocation was successful
  //! 
  bool DETECTORDLL_API allocateVehicleDetector(VehicleDetector **oVD, 
                                               VehicleDetectionConfiguration **oVDC);

  //! @brief Deallocate a vehicle detection implementation
  //!
  //! @param[in] iVD		a pointer to the detector implementation
  //! @param[in] iVDC		a pointer to the detector configuration
  //! 
  //! After deallocation call, pointers' values are undefined
  //!
  void DETECTORDLL_API freeVehicleDetector(VehicleDetector *iVD, 
                                           VehicleDetectionConfiguration *iVDC);

  //! @brief Load a learned classifier
  //!
  //! @param[in]  iID  id of the classifer
  //! @param[out] oVD  The classifier is loaded and stored
  //!
  //! @return Boolean indicating whether load was successful
  //!
  bool DETECTORDLL_API loadVehicleDetectionClassifier(const char *iID, 
                                                      VehicleDetector* oVD);

  //! @brief Detect and classify vehicles in the scene
  //!
  //! @param[in]  iVDI	The image to process
  //! @param[in]  iVDC	The detection configuration
  //! @param[in]  iVD		The classifier
  //! @param[out] oVDR	The detection results
  //! 
  //! @return true if the classification process finished successfully
  //!
  bool DETECTORDLL_API runVehicleDetection(const VehicleDetectionImage* iVDI, 
                                           VehicleDetectionConfiguration *iVDC, 
                                           VehicleDetector* iVD, 
                                           VehicleDetectionResult *oVDR);

  //! @brief Determine number of detections found
  //!
  //! @param[in] iVDR		The classifier
  //!
  //! @return The number of vehicles detected (zero based)
  //!
  //! Returning a zero means no vehicles were detected
  //!
  int DETECTORDLL_API numVehicleDetections(VehicleDetectionResult* iVDR);

  //! @brief Access a specific vehicle detection
  //! 
  //! @param[in]  iVDR      The Vehicle detection results
  //! @param[in]  iIndex 	  The index in the results list to access
  //! @param[out] oVD       The vehicle detection
  //!
  //! @return True if a detection at iIndex exists
  //!
  //! Note that iIndex should be less than the return of numVehicleDetections
  //!
  bool DETECTORDLL_API getVehicleDetection(VehicleDetectionResult* iVDR, 
                                           int iIndex, 
                                           VehicleDetection **oVD);

  //! @brief Load Detection Configuration from configuration
  //! 
  //! @param[in]  iVDR      The Vehicle detection configuration
  //! @param[out] oVD       The vehicle detection
  //!
  //! @return True if the detector configurations are loaded successfully
  //!
  bool DETECTORDLL_API loadDetectorConfiguration(VehicleDetectionConfiguration *iVDC, 
                                                 VehicleDetector* oVD);

  //! @brief Deallocate memory of VehicleDetectionResult vector and detection results
  //! 
  //! @param[in]  iVDR      The vector of detection results

  //! After De-allocation pointer's value is undefined
  //!
  void DETECTORDLL_API freeVehicleDetectionResult(VehicleDetectionResult *iVDR);

  //! @brief Filter detection responses of the current frame by 
  //!        matching these responses with the detection history
  //! 
  //! @param[in]  iVD      Pointer to hidden implementation 
  //! @param[in]  iVDC	 Detection Configurations
  //! @param[out] oVDR	 Modified detection results
  //!
  //! @return True if the detection results are filtered successfully
  //!
  bool DETECTORDLL_API filterDetectionResponses(VehicleDetector *iVD, 
                                                VehicleDetectionConfiguration *iVDC,
                                                VehicleDetectionResult *oVDR);

  //! @brief Free the memory from detection result history 
  //! 
  //! @param[in]  iVD      Pointer to Vehicle Detector 
  //! @param[in]  size	 Number of enteries to be removed from the detection history
  //!
  //! Number of entries are removed from the detection result history
  //!
  void DETECTORDLL_API deleteVehicleHistory(VehicleDetector *iVD, int size);

  //! @brief Allocate memory to vehicle detection result structure 
  //! 
  //! @param[out]  oVDR      The vehicle detection results
  //!
  //! @return True if the memory is allocated successfully
  //!
  bool DETECTORDLL_API allocateVehicleDetectionResult(VehicleDetectionResult **oVDR);

  //! @brief Allocate memory to the vehicle homography structure
  //! 
  //! @param[in]   iVDC    The detection configuration parameters
  //! @param[out]  oVHO    The Vehicle Homography
  //!
  //! @return True if the memory is allocated successfully
  //!
  bool DETECTORDLL_API allocateVehicleHomography(VehicleHomography **oVHO, 
                                                 VehicleDetectionConfiguration *iVDC);

#ifdef __cplusplus
}
#endif

#endif